#include "../LogSystem/senlog.h"
#include <vector>
#include <thread>
#include <chrono>
void bench(const std::string logname, size_t thread_num, size_t msg_count, size_t msg_size)
{
    // 获取日志器
    senlog::Logger::ptr logger = senlog::getLogger(logname);
    if (logger.get() == nullptr)
        return;

    std::cout << "测试信息："<< msg_count << "条, 共计"<< (msg_count*msg_size)/(1024) << "KB" << std::endl;

    // 组织指定长度日志消息
    std::string msg(msg_size - 1, 'x'); // mes_size - 1是为了添加换行'\n'便于观察
    // 创建指定数量线程
    std::vector<std::thread> threads;
    std::vector<double> costs(thread_num);
    size_t msg_pre_thread = msg_count / thread_num; // 每个线程平均输出数量
    for (int i = 0; i < thread_num; i++)
    {
        threads.emplace_back([&, i]()
                             {
                                 // 开始计时
                                 auto start = std::chrono::high_resolution_clock::now();
                                // 循环写入日志
                                 for (int j = 0; j < msg_pre_thread; j++)
                                 {
                                     logger->fatal("%s", msg.c_str());
                                 }
                                 auto end = std::chrono::high_resolution_clock::now();
                                 std::chrono::duration<double> cost = end - start;
                                costs[i] = cost.count();
                                // 结束测试
                                 std::cout << "线程 " << i << " 输出日志数量: " << msg_pre_thread << ", 总耗时: " << cost.count() << "秒" << std::endl;
                             }); // 构造 并 插入

    }

    for(int i = 0; i < thread_num; i++)
    {
        threads[i].join();
    }
    //总耗时 ： 所有线程耗时中 最大的一个
    double max_cost = costs[0];
    for(int i = 0; i < costs.size(); i++)
    {
        if(costs[i] > max_cost)
            std::swap(max_cost, costs[i]);
    }
    //

    //每秒输出日志条数
    size_t msg_pre_sec = msg_count / max_cost;

    //每秒输出日志大小
    size_t msg_size_sec = (msg_count * msg_size) / (max_cost * 1024);
    std::cout << "每秒输出日志" << msg_pre_sec << "条" << std::endl;  
    std::cout << "每秒输出日志大小(KB)" << msg_size_sec << "KB" << std::endl;
}

void syncBench()
{
    std::unique_ptr<senlog::LoggerBuilder> builder(new senlog::GlobalLoggerBuilder());
    builder->buildLoggerName("sync_logger");
    builder->buildFormatterPtr("%m%n");
    builder->buildLoggerType(senlog::LoggerType::SYNC_LOGGER);
    builder->buildSink<senlog::FileLogSink>("./logfile/sync.log");
    builder->build();

    bench("sync_logger", 3, 1000000, 100);
    //多线程中，存在锁冲突，所以多线程反而比单线程效率低
}
void asyncBench()
{
    std::unique_ptr<senlog::LoggerBuilder> builder(new senlog::GlobalLoggerBuilder());
    builder->buildLoggerName("async_logger");
    builder->buildFormatterPtr("%m%n");
    builder->buildLoggerType(senlog::LoggerType::ASYN_LOGGER);
    builder->buildEnableUnsafe(); // 开启非安全模式————非阻塞
    builder->buildSink<senlog::FileLogSink>("./logfile/async.log");
    builder->build();

    bench("async_logger", 3, 1000000, 100);
    //多线程中，存在锁冲突，所以多线程反而比单线程效率低
}

int main()
{
    //syncBench();
    asyncBench();
    return 0;
}